package com.lastproject.web.bean;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.EJB;
import javax.faces.context.FacesContext;

import com.lastproject.dto.AnswerDTO;
import com.lastproject.dto.CategoryDTO;
import com.lastproject.dto.EmailGroupDTO;
import com.lastproject.dto.QuestionDTO;
import com.lastproject.dto.SubcategoryDTO;
import com.lastproject.dto.SurveyDTO;
import com.lastproject.dto.UserDTO;
import com.lastproject.ejb.dao.AnswerDAORemote;
import com.lastproject.ejb.dao.CategoryDAORemote;
import com.lastproject.ejb.dao.EmailGroupDAORemote;
import com.lastproject.ejb.dao.QuestionDAORemote;
import com.lastproject.ejb.dao.SubcategoryDAORemote;
import com.lastproject.ejb.dao.SurveyDAORemote;
import com.lastproject.ejb.dao.TopicDAORemote;

public class SurveyBeanAnswers {

	@EJB
	SurveyDAORemote surveyDAO;
	@EJB
	QuestionDAORemote questionDAO;
	@EJB
	CategoryDAORemote categoryDAO;
	@EJB
	SubcategoryDAORemote subcategoryDAO;
	@EJB
	TopicDAORemote topicDAO;
	@EJB
	EmailGroupDAORemote groupDAO;
	@EJB
	AnswerDAORemote AnswerDAO;

	private SurveyDTO surveyDTO;

	private CategoryDTO category;
	private SubcategoryDTO subcategory;

	private List<QuestionBean> questions;

	private QuestionBean qb;

	public QuestionBean getQb() {
		return qb;
	}

	public void setQb(QuestionBean qb) {
		this.qb = qb;
	}

	/**
	 * initiates the a survey: sets the surveyDTO,category,subcategory and
	 * questions attributes according to the selected survey
	 * 
	 * @return
	 * @param the
	 *            id of the survey to be initiated
	 */

	void init(int id) {
		surveyDTO = surveyDAO.findById(id);
		category = categoryDAO.findById(topicDAO.findById(
				surveyDTO.getIdTopic()).getIdCategory());
		subcategory = subcategoryDAO.findById(topicDAO.findById(
				surveyDTO.getIdTopic()).getIdSubcategory());

		questions = getAllQuestionBean(id);
		isEmpty = "";
	}

	public SurveyDTO getSurveyDTO() {
		return surveyDTO;
	}

	public void setSurveyDTO(SurveyDTO surveyDTO) {
		this.surveyDTO = surveyDTO;
	}

	public List<QuestionBean> getQuestions() {
		return questions;
	}

	public void setQuestions(List<QuestionBean> questions) {
		this.questions = questions;
	}

	public CategoryDTO getCategory() {
		return category;
	}

	public void setCategory(CategoryDTO category) {
		this.category = category;
	}

	public SubcategoryDTO getSubcategory() {
		return subcategory;
	}

	public void setSubcategory(SubcategoryDTO subcategory) {
		this.subcategory = subcategory;
	}

	/**
	 * saves the answers for each individual question in the survey if no
	 * question is answered an error message is instantiated
	 * 
	 * @return null
	 */
	public String save() {
		isEmpty = "";
		for (QuestionBean q : questions)
			if (!qb.save(q))
				isEmpty = "Please fill in at least one question!";
		return null;
	}

	/**
	 * retrieves all surveys (a survey represents a SurveyBeanAnswers) of the
	 * logged in user
	 * 
	 * @return a list of SurveyBeans
	 */
	public List<SurveyBeanAnswers> getMySurveys() {
		List<SurveyBeanAnswers> surveyBeans = new ArrayList<>();
		FacesContext f = FacesContext.getCurrentInstance();
		UserDTO userDTO = (UserDTO) f.getExternalContext().getSessionMap()
				.get("userDTO");
		List<EmailGroupDTO> groups = groupDAO.findGroupsByUserId(userDTO
				.getId());
		List<SurveyDTO> surveys = new ArrayList<>();

		for (EmailGroupDTO g : groups) {

			// abcdEFGH1234
			List<SurveyDTO> s = surveyDAO.getSurveysByGroupId(g.getId());
			if (s != null)
				surveys.addAll(s);
		}

		for (SurveyDTO survey : surveys) {
			SurveyBeanAnswers s = new SurveyBeanAnswers();
			s.setSurveyDTO(survey);
			surveyBeans.add(s);
		}
		// OK
		return surveyBeans;
	}

	/**
	 * Verifies that the survey is still valid(if no questions were answered)
	 * 
	 * @return a boolean value true if the survey is still valid and false
	 *         otherwise
	 */
	public boolean valid() {

		boolean valid = true;
		done = "";
		FacesContext f = FacesContext.getCurrentInstance();
		UserDTO userDTO = (UserDTO) f.getExternalContext().getSessionMap()
				.get("userDTO");
		for (QuestionBean q : questions)
			for (QuestionOptionBean qo : q.getList()) {
				for (AnswerDTO answer : AnswerDAO
						.getAnswersByQuestionOptionId(qo.getQuestionOptionDTO()
								.getId()))
					if (answer.getIdUser() == userDTO.getId()) {
						valid = false;
						done = "Thank you for taking your time to fill in our survey!";
						isEmpty = "";
					}
			}
		return valid;

	}

	/**
	 * retrieves all Questions(a question represents a QuestionBean) of the
	 * current survey and groups the options in 4 different lists according to
	 * their type: single choice , multiple choice , plain text and grade
	 * 
	 * @return a list of SurveyBeans
	 */
	public List<QuestionBean> getAllQuestionBean(int id) {
		List<QuestionBean> list = new ArrayList<>();
		List<QuestionDTO> aux = new ArrayList<>();

		aux.addAll(questionDAO.getQuestionListBySurveyId(id));

		for (QuestionDTO question : aux) {
			QuestionBean q = new QuestionBean();
			List<QuestionOptionBean> s = new ArrayList<>();
			List<QuestionOptionBean> m = new ArrayList<>();
			List<QuestionOptionBean> t = new ArrayList<>();
			List<QuestionOptionBean> r = new ArrayList<>();
			List<Integer> selected = new ArrayList<>();
			q.setQuestionDTO(question);
			q.setList(qb.getAllQuestionOptionBean(question.getId()));
			for (QuestionOptionBean qob : q.getList())
				switch (qob.getQuestionOptionDTO().getType()) {
				case "singleChoice":
					s.add(qob);
					if (qob.getQuestionOptionDTO().getTextDefault() != null)
						q.setSelectedItem((Integer) qob.getQuestionOptionDTO()
								.getId());
					break;
				case "multipleChoice":
					m.add(qob);
					if (qob.getQuestionOptionDTO().getTextDefault() != null)
						selected.add((Integer) qob.getQuestionOptionDTO()
								.getId());
					break;
				case "plainText":
					t.add(qob);
					break;
				case "grade":
					r.add(qob);
					break;
				default:
					break;
				}
			q.setSimple(s);
			q.setMultiple(m);
			q.setText(t);
			q.setRank(r);
			q.setSelectedItems(selected);
			list.add(q);
		}
		return list;
	}

	public String done;
	public String isEmpty;

	public String getDone() {
		return done;
	}

	public void setDone(String done) {
		this.done = done;
	}

	public String getIsEmpty() {
		return isEmpty;
	}

	public void setIsEmpty(String isEmpty) {
		this.isEmpty = isEmpty;
	}

}
